package jwtMinddle

import (
	"fmt"
	"github.com/golang-jwt/jwt/v5"
	"time"
	"utilsx/constant"
)

type UserClaims[T any] struct {
	*jwt.RegisteredClaims
	UserId int32 `json:"id"`
	Data   *T    `json:"data"`
}

func CreatJwtTokenWithClaims[T any](uc UserClaims[T]) (string, error) {
	nowTime := time.Now()
	uc.RegisteredClaims = &jwt.RegisteredClaims{
		ExpiresAt: &jwt.NumericDate{Time: nowTime.Add(constant.JwtExpiresAt)},
		Issuer:    constant.JwtSecretIssuer,        // 签发人
		IssuedAt:  &jwt.NumericDate{Time: nowTime}, //签发时间
	}
	claims := jwt.NewWithClaims(jwt.SigningMethodHS256, uc)
	// 使用指定的secret签名,获取字符串token
	tokenStr, err := claims.SignedString([]byte(constant.JwtSecret))
	if err != nil {
		return "", err
	}
	return tokenStr, nil
}

func ParseWithClaims[D any](tokenString string) (*UserClaims[D], error) {
	// 如果令牌无效（如果令牌已根据我们设置的登录到期时间过期）或者签名不匹配,此方法会返回错误.
	var t = new(UserClaims[D])
	token, err := jwt.ParseWithClaims(tokenString, t, func(token *jwt.Token) (any, error) {
		if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
			return nil, fmt.Errorf("UnexpectedSigningMethod: %v", token.Header["alg"])
		}
		return []byte(constant.JwtSecret), nil
	})
	if err != nil {
		return nil, err
	}
	if claims, ok := token.Claims.(*UserClaims[D]); ok && token.Valid {
		return claims, nil
	}
	return nil, err
}
func ParseWithClaims2[D any](tokenString string) (*UserClaims[D], error) {
	// 如果令牌无效（如果令牌已根据我们设置的登录到期时间过期）或者签名不匹配,此方法会返回错误.
	var t = new(UserClaims[D])
	token, err := jwt.ParseWithClaims(tokenString, t, func(token *jwt.Token) (any, error) {
		if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
			return nil, fmt.Errorf("UnexpectedSigningMethod: %v", token.Header["alg"])
		}
		return []byte(constant.JwtSecret), nil
	})
	if err != nil {
		return nil, err
	}
	if claims, ok := token.Claims.(*UserClaims[D]); ok && token.Valid {
		return claims, nil
	}
	return nil, err
}
